package zhh.tangbao.system.config;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import zhh.tangbao.system.dto.FileUploadRuleDto;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 *     通过分别维护limitRule、fileAccessPathRule、filePhysicalPathRule三个HashMap来储存不同类型文件的相关信息
 * </p>
 * <p>
 *     <strong>limitRule </strong>{key: 文件类型名称, value: 文件大小限制}：不同文件类型可上传的大小限制 <br>
 *     <strong>fileAccessPathRule</strong>{key: 文件类型名称, value: 访问地址}：不同文件类型的文件访问地址 <br>
 *     <strong>filePhysicalPathRule</strong>{key: 文件类型名称}：不同文件类型存放在服务器上的真实路径
 * </p>
 * @author 粥灰灰
 * <p>2023/3/2</p>
 */

@Configuration
public class FileUploadConfig {
    private final HashMap<String, Long> limitRule = new HashMap<>();

    private final HashMap<String, String> fileAccessPathRule = new HashMap<>();

    private final HashMap<String, String> filePhysicalPathRule = new HashMap<>();

    /**
     * 大型文件默认最大大小限制
     */
    @Value("${custom.fileUploadRule.bigFileDefaultSizeLimit}")
    private Long bigFileDefaultSizeLimit;

    /**
     * 小型文件默认最大大小限制
     */
    @Value("${custom.fileUploadRule.smallFileDefaultSizeLimit}")
    private Long smallFileDefaultSizeLimit;

    /**
     * 其他类型文件的默认访问路径
     */
    @Value("${custom.fileUploadRule.fileDefaultAccessPath}")
    private String fileDefaultAccessPath;

    /**
     * 其他类型文件的默认物理存放路径
     */
    @Value("${custom.fileUploadRule.fileDefaultPhysicalPath}")
    private String fileDefaultPhysicalPath;

    @Value("${custom.fileUploadRule.imgACPath}")
    private String imgACPath;

    @Value("${custom.fileUploadRule.imgPCPath}")
    private String imgPCPath;

    @Value("${custom.fileUploadRule.officeACPath}")
    private String officeACPath;

    @Value("${custom.fileUploadRule.officePCPath}")
    private String officePCPath;


    /*
     * 初始化
     */
    @PostConstruct
    void init() {
        // 常见图片文件类型
        String[] img = {"jpg", "png", "jpeg", "bmp", "dib", "tif", "tiff", "gif",};
        // 文件类型的大小限制为10MB
        setFileLimitRule(img, smallFileDefaultSizeLimit);
        setFilePhysicalPathRule(img, imgPCPath);
        setFileAccessPathRule(img, imgACPath);
        // 常见office文件类型
        String[] office = {"pdf", "xls", "xlsx", "doc", "docx", "txt", "ppt", "pptx"};
        // office文件大小限制为
        setFileLimitRule(office, bigFileDefaultSizeLimit);
        setFilePhysicalPathRule(office, officePCPath);
        setFileAccessPathRule(office, officeACPath);

    }


    private void setFileAccessPathRule(String[] types, String path) {
        for (int i = 0; i < types.length; i++) {
            fileAccessPathRule.put(types[i], path);
        }
    }

    private void setFilePhysicalPathRule(String[] types, String path) {
        for (int i = 0; i < types.length; i++) {
            filePhysicalPathRule.put(types[i], path);
        }
    }

    /**
     * 给不同文件类型组设置不同的大小限制规则
     * @param types 文件类型组
     * @param limitSize 最大上传大小，单位：B
     */
    private void setFileLimitRule(String[] types, Long limitSize) {
        for (int i = 0; i < types.length; i++) {
            limitRule.put(types[i], limitSize);
        }
    }

    /**
     * 根据对应的文件类型名称获取相应的上传文件大小限制
     * @param fileType 文件类型
     * @return
     */
    public Long getLimitSize(String fileType) {
        Long limit = limitRule.get(fileType.toLowerCase());
        if (null == limit) {
            // 如果文件类型表中没有对应类型则默认限制为1GB
            return bigFileDefaultSizeLimit;
        }
        return limit;
    }

    /**
     * 获取文件的访问地址
     * @param type 文件类型名称
     * @return
     */
    public String getFileAccessPath(String type) {
        String t = type.toLowerCase();
        String s = fileAccessPathRule.get(t);
        if (StrUtil.isEmpty(s)) {
            return fileDefaultAccessPath;
        }
        return s;
    }

    /**
     * 获取文件的物理（真实）存放路径，即在服务器上存放的路径
     * @param type 文件类型名称
     * @return
     */
    public String getFilePhysicalPath(String type) {
        String t = type.toLowerCase();
        String s = filePhysicalPathRule.get(t);
        if (StrUtil.isEmpty(s)) {
            return fileDefaultPhysicalPath;
        }
        return s;
    }

}
